var TuTip = (function(self, $) {
	
	var _options = {
		debug: false,
		type: 'manual',
		millis: 3000
	};
	
	self.FOCUS = {
		TOP_LEFT: 'top left', 
		TOP_RIGHT: 'top right', 
		TOP_CENTER: 'top center',
		BOTTOM_LEFT: 'bottom left', 
		BOTTOM_RIGHT: 'bottom right', 
		BOTTOM_CENTER: 'bottom center',
		RIGHT_CENTER: 'right center', 
		RIGHT_TOP: 'right top', 
		RIGHT_BOTTOM: 'right bottom',
		LEFT_CENTER: 'left center', 
		LEFT_TOP: 'left top', 
		LEFT_BOTTOM: 'left bottom', 
		CENTER: 'center'
	};
	
	self.STYLES = {
		NONE: '',
		RED: '-red', 
	 	BLUE: '-blue', 
	 	DARK: '-dark', 
	 	LIGHT: '-light', 
	 	GREEN: '-green', 
	 	JTOOLS: '-jtools', 
	 	PLAIN: '-plain', 
	 	YOUTUBE: '-youtube', 
	 	CLUETIP: '-cluetip', 
	 	TIPSY: '-tipsy', 
	 	TIPPED: '-tipped', 
	 	BOOTSTRAP: '-bootstrap',
		ROUNDED: '-rounded'
	};
	
	self.stepConfig = function(){
		this.target = $('body');
		this.title = 'Title';
		this.content = 'Content';
		this.tipFocus = 'center';
		this.elFocus = 'center';
		this.style = '';
	};
	
	self.steps = [
		{ target: $('#test-1'), title: 'Welcome to step 1!', content: 'Description...', tipFocus: self.FOCUS.LEFT_TOP, elFocus: self.FOCUS.BOTTOM_RIGHT, style: self.STYLES.DARK },
	    { target: $('#test-2'), title: 'Step 2...', content: 'We are...', tipFocus: self.FOCUS.LEFT_TOP, elFocus: self.FOCUS.BOTTOM_RIGHT, style: self.STYLES.DARK }
	];
	
	self.about = {
		name: 'TuTip',
		version: '0.1'
	};

	self.init = function(options) {
		// Apply options
		$.extend(true, _options, options);

		// Enable debug logging
		if(_options.debug) {
			self.log = function(str) {
				try { // prevent erroring
					if(typeof window.console !== undefined && typeof window.console.log !== undefined) {
						console.log(str);
					}
				} catch(e) {
					alert('[Debug] logging not possible.');
				}
			};
			self.log('[Init] Debugging enabled.');
		}
		
		self.log('[Init] Done.');
		self.beginTutorial();
	};
	
	self.beginTutorial = function() {
		try{
			$(document.body).qtip({
		        id: 'step',
		        // Give it an ID of ui-tooltip-step so we an identify it easily
		        content: {
		            text: self.steps[0].content,
		            // Use first steps content...
		            title: {
		                text: self.steps[0].title,
		                // ...and title
		                button: true
		            }
		        },
		        position: {
		            my: self.steps[0].tipFocus,
		            at: self.steps[0].elFocus,
		            target: self.steps[0].target,
		            // Also use first steps position target...
		            viewport: $(window) // ...and make sure it stays on-screen if possible
		        },
		        show: {
		            event: false,
		            // Only show when show() is called manually
		            ready: true // Also show on page load
		        },
		        hide: false,
		        // Don't' hide unless we call hide()
		        events: {
		            render: function(event, api) {
		                // Grab tooltip element
		                var tooltip = api.elements.tooltip;
		 
		                // Track the current step in the API
		                api.step = 0;
		 
		                // Bind custom custom events we can fire to step forward/back
		                tooltip.bind('next prev', function(event) {
		                    // Increase/decrease step depending on the event fired
		                    api.step += event.type === 'next' ? 1 : -1;
		                    api.step = Math.min(self.steps.length - 1, Math.max(0, api.step));
		 
		                    // Set new step properties
		                    var current = self.steps[api.step];
		                    if (current) {
		                        api.set({
		                            'content.text': current.content,
		                            'content.title.text': current.title,
		                            'position.target': current.target,
		                            'position.my': current.tipFocus,
		                            'position.at': current.elFocus,
		                            'style.classes': 'ui-tooltip-shadow ui-tooltip' + current.style
		                        });
		                    }
		                });
		            }
		        },
		        style: {
		            classes: 'ui-tooltip-shadow ui-tooltip' + self.steps[0].style,
		            def: false
		        }
		    });
		 
		    // Inject control div
		    var $ctrlDiv = $('<div id="t-btm-center-menu">'+
		                         '<ul>'+
		                            '<li><a id="start" href="#">Begin</a></li>'+
		                            '<li><a id="prev" href="#">&lt; Prev</a></li>'+
		                            '<li><a id="next" href="#">Next &gt;</a></li>'+
		                            '<li><a id="end" href="#">End</a></li>'+
		                        '</ul>'+
		                     '</div>');
		    $('body').append($ctrlDiv);
		 
		    // Setup the next/prev links
		    $('#next, #prev').bind('click', function(event) {
		        var tooltip = $('#ui-tooltip-step');
		 
		        // If it isn't visible don't do anything
		 
		 
		        // Trigger the tooltip event
		        tooltip.triggerHandler(this.id);
		 
		        // Stop the link from actually clicking
		        event.preventDefault();
		    });
		 
		    // Setup the start/end links
		    $('#start, #end').bind('click', function(event) {
		        var api = $('#ui-tooltip-step').qtip();
		 
		        // Reset the API step to -1
		        api.step = -1;
		 
		        if (this.id === 'start') {
		            // Trigger next handler to update content with first step
		            api.elements.tooltip.triggerHandler('next');
		 
		            // Show tooltip and next/prev buttons
		            api.show();
		            $('#next, #prev').show();
		        }
		 
		        // If we're ending the tour, hide the tooltip and the next/prev links
		        else {
		            api.hide();
		            $('#next, #prev').hide();
		        }
		        // Stop the link from actually clicking
		        event.preventDefault();
		    });
		}catch(exception){
			self.log('[beginTutorial] Exception: ' + exception);
		}
	};
	
	self.addTipToDraggable = function(el, description, title, closeable, style) {
		try {
			$(el)	// Deletes the qTip data from the target element allowing for multiple tooltips.
			.removeData('qtip').qtip({
				content: {
					text: description,
					title: {
						text: title,
						button: closeable
					}
				},
				position: { // function assumes automatic positioning possibly for dragging
					at: $('#at').val(),
					my: $('#my').val(),
					viewport: $(window),
					adjust: {
						method: $('#adjust_method').val(),
						x: parseInt($('#adjust_x').val(), 10) || 0,
						y: parseInt($('#adjust_y').val(), 10) || 0
					}
				},
				show: {
					event: false, // Don't specify a show event...
					ready: true // ... but show the tooltip when ready
				},
				hide: false, // Don't specify a hide event either!
				style: {
					classes: 'ui-tooltip-shadow ui-tooltip' + style
				}
			});
		}catch(exception){
			self.log('[addTipToDraggable] Exception: ' + exception);
		}
	};
	
	self.addTip = function(el, description, title, closeable, style, tipFocus, elFocus) {
		try {
			$(el)	// Deletes the qTip data from the target element allowing for multiple tooltips.
			.removeData('qtip').qtip({
				content: {
					text: description,
					title: {
						text: title,
						button: closeable
					}
				},
				position: {
					at: tipFocus,
					my: elFocus
				},
				show: {
					event: false, // Don't specify a show event...
					ready: true // ... but show the tooltip when ready
				},
				hide: false, // Don't specify a hide event either!
				style: {
					classes: 'ui-tooltip-shadow ui-tooltip' + style
				}
			});
		}catch(exception){
			self.log('[addTip] Exception: ' + exception);
		}
	};
	
	self.addStep = function(target, title, content, tipFocus, elFocus, style) {
		try {
			// TODO: Add error checking/handling
			if (typeof self.steps !== undefined && self.steps instanceof Array) {
				self.steps.push({
					target: $(target),
					title: title,
					content: content,
					tipFocus: tipFocus,
					elFocus: elFocus,
					style: style
				});
			}
		} catch (exception){
			self.log('[addStep] Exception: ' + exception);
		}
	};
	
	self.removeStep = function () {
		try {
			self.steps.pop();
		} catch (exception){
			self.log('[removeStep] Exception: ' + exception);
		}
	};

	self.setCookie = function(name, value, lifetime_days) {
		try {
			var exp = new Date();
			exp.setDate(new Date().getDate() + lifetime_days);
			document.cookie = name + '=' + value + ';expires=' + exp.toUTCString() + ';path=/';
		} catch (exception) {
			self.log('[setCookie] Exception: ' + exception);
		}
	};

	self.cookieExists = function(name) {
		try {
			return document.cookie.indexOf(name) > -1;
		} catch (exception) {
			self.log('[cookieExists] Exception: ' + exception);
		}
	};

	self.getCookie = function(name) {
		try {
			if (document.cookie) {
				var regex = new RegExp(escape(name) + '=([^;]*)', 'gm'), matches = regex.exec(document.cookie);
				if (matches) {
					return matches[1];
				}
			}
		}catch (exception){
			self.log('[getCookie] Exception: ' + exception);
		}
	};

	self.deleteCookie = function(name) {
		try {
			document.cookie = name + '=;expires=Thu, 01-Jan-70 00:00:01 GMT;path=/';
		} catch(exception){
			self.log('[deleteCookie] Exception: ' + exception);
		}
	};
	
	self.log = function() {};

	return self;
}(TuTip || {}, jQuery));
